#!/usr/bin/env bash

#
# 单独抽取的 map-reduce crash 测试脚本
#

# 保持环境检测逻辑（可选，若需兼容原环境判断可保留）
RACE=-race
if [[ "$OSTYPE" = "darwin"* ]]; then
    if go version | grep 'go1.17.[012345]'; then
        RACE=
        echo '*** Turning off -race since it may not work on a Mac'
        echo '    with ' `go version`
    fi
fi

TIMEOUT=timeout
if timeout 2s sleep 1 > /dev/null 2>&1; then
    :
else
    if gtimeout 2s sleep 1 > /dev/null 2>&1; then
        TIMEOUT=gtimeout
    else
        TIMEOUT=
        echo '*** Cannot find timeout command; proceeding without timeouts.'
    fi
fi
if [ "$TIMEOUT" != "" ]; then
    TIMEOUT+=" -k 2s 180s "
fi

# 初始化测试目录
rm -rf mr-tmp
mkdir mr-tmp || exit 1
cd mr-tmp || exit 1
rm -f mr-*

# 确保编译相关程序（只保留 crash 测试需要的编译）
(cd ../../mrapps && go clean)
(cd .. && go clean)
(cd ../../mrapps && go build $RACE -buildmode=plugin nocrash.go) || exit 1
(cd ../../mrapps && go build $RACE -buildmode=plugin crash.go) || exit 1
(cd .. && go build $RACE mrcoordinator.go) || exit 1
(cd .. && go build $RACE mrworker.go) || exit 1
(cd .. && go build $RACE mrsequential.go) || exit 1

failed_any=0

#########################################################
# crash test 单独测试
echo '***' Starting crash test.

# 生成正确输出（依赖 mrsequential 和 nocrash.so）
../mrsequential ../../mrapps/nocrash.so ../pg*txt || exit 1
sort mr-out-0 > mr-correct-crash.txt
rm -f mr-out*

rm -f mr-done
($TIMEOUT stdbuf -oL ../mrcoordinator ../pg*txt ; touch mr-done ) &
sleep 1

# 启动 worker（模拟 crash 场景）
$TIMEOUT stdbuf -oL ../mrworker ../../mrapps/crash.so &

# 模拟 rpc.go 的 coordinatorSock()
SOCKNAME=/home/user_yi/824-mr-`id -u`

( while [ -e $SOCKNAME -a ! -f mr-done ]; do
    $TIMEOUT stdbuf -oL ../mrworker ../../mrapps/crash.so
    sleep 1
done ) &

( while [ -e $SOCKNAME -a ! -f mr-done ]; do
    $TIMEOUT stdbuf -oL ../mrworker ../../mrapps/crash.so
    sleep 1
done ) &

while [ -e $SOCKNAME -a ! -f mr-done ]; do
    $TIMEOUT stdbuf -oL ../mrworker ../../mrapps/crash.so
    sleep 1
done

wait

rm $SOCKNAME
sort mr-out* | grep . > mr-crash-all

# 验证结果
if cmp mr-crash-all mr-correct-crash.txt; then
    echo '---' crash test: PASS
else
    echo '---' crash output is not the same as mr-correct-crash.txt
    echo '---' crash test: FAIL
    failed_any=1
fi

#########################################################
# 最终结果判断
if [ $failed_any -eq 0 ]; then
    echo '***' PASSED CRASH TEST
else
    echo '***' FAILED CRASH TEST
    exit 1
fi